﻿using System;
using System.Collections.Generic;
using System.Text;

namespace llAma
{
    public enum Comparison
    {
        GT = 1,
        LT,
        EQ,
        GTEQ,
        LTEQ,
        NEQ,
        NOP // Do not compare (always returns false)

    }
    public class PermissionRuleSet : IEnumerable<PermissionRule>
    {
        Dictionary<string, PermissionRule> mRules = new Dictionary<string, PermissionRule>();
        public PermissionRule this[string key]
        {
            get
            {
                if (mRules.ContainsKey(key.ToLower()))
                    return mRules[key.ToLower()];
                return null;
            }
            set
            {
                mRules[key.ToLower()] = value;
            }
        }
        public bool HasRule(PermissionRule p)
        {
            return (this[p.Name] != null);
        }
        public bool Demand(PermissionRule p)
        {
            if (!HasRule(p)) return false;
            return p.Demand(this[p.Name]);
        }

        IEnumerator<PermissionRule> IEnumerable<PermissionRule>.GetEnumerator()
        {
            return ((IEnumerable<PermissionRule>)mRules.Values).GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return ((IEnumerable<PermissionRule>)mRules.Values).GetEnumerator();
        }

        public void RemoveRule(PermissionRule p, bool sameValueOnly)
        {
            if (this.HasRule(p))
            {
                if (!sameValueOnly || this[p.Name].Value == p.Value)
                {
                    this.mRules.Remove(p.Name.ToLower());
                }
            }
        }
        public void RemoveRuleSet(PermissionRuleSet pr)
        {
            RemoveRuleSet(pr, true);
        }
        public void RemoveRuleSet(PermissionRuleSet pr, bool sameValueOnly)
        {
            foreach (PermissionRule p in pr)
            {
                RemoveRule(p, sameValueOnly);
            }
        }

        private void RemoveRule(PermissionRule p)
        {
            RemoveRule(p, true);
        }
    }
    public class PermissionRule
    {
        private string mName;
        private int mVal;
        private Comparison OP;
        public string Name
        {
            get { return mName; }
        }
        public int Value
        {
            get { return mVal; }
        }
        public PermissionRule(string name, int val)
            : this(name, val, Comparison.GTEQ)
        {
        }
        public PermissionRule(string name, int val, Comparison checkType)
        {
            mName = name;
            mVal = val;
            OP = checkType;
        }
        public bool Demand(PermissionRule p)
        {
            if (p.mName.ToLower() != mName.ToLower())
                throw new InvalidOperationException("Tried to compare two different rules!");
            switch (OP)
            {
                case Comparison.GT:
                    return (mVal > p.mVal);
                case Comparison.GTEQ:
                    return (mVal >= p.mVal);
                case Comparison.EQ:
                    return (mVal == p.mVal);
                case Comparison.NEQ:
                    return (mVal != p.mVal);
                case Comparison.LTEQ:
                    return (mVal <= p.mVal);
                case Comparison.LT:
                    return (mVal < p.mVal);
                default:
                    //why the fuck did we get here?
                    return false;
            }
        }
    }
}
